﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace debugger
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        public Form1 mainForm;

        private void Form2_Load(object sender, EventArgs e)
        {
        }
        public class MemPage
        {
            public int page;
            public uint[] data = new uint[256];
        }


        MemPage[] pages = new MemPage[1 + 1];

        private void confirm(MemPage page, int offset, StringBuilder sb)
        {
            int pageA = page.page;
            uint[] dataA = page.data;

            uint addr = (uint)((pageA << 10) + offset);
            uint val = mainForm.getmem(addr, null);
            if (sb != null)
            {
                if (val != dataA[offset >> 2])
                {
                    sb.Append(" access time:");
                    sb.Append(mainForm.getAccessTime());
                    sb.Append("addr:" + Util.getHex8(addr) + ",data:" + Util.getHex8(dataA[offset >> 2]) + ",mem:" + Util.getHex8(val));
                    sb.AppendLine();
                }
            }
        }



        private void button7_Click(object sender, EventArgs e)
        {
            memtest((uint)(8 * 1024 * 1024));
        }

        void memtest(uint size)
        {

            for (int i = 0; i < 5; i++)
            {
                Bitmap bmp = new Bitmap(256, 256);

                uint len = size;// 1 * 128 * 1024;
                byte[] data = new byte[len];
                if (i == 0)
                {
                    Random r = new Random();
                    r.NextBytes(data);
                }
                if (i == 1)
                {
                    for (int j = 0; j < len; j++)
                    {
                        data[j] = 0;
                    }
                }
                if (i == 2)
                {
                    for (int j = 0; j < len; j++)
                    {
                        data[j] = 0xFF;
                    }
                }
                if (i == 3)
                {
                    for (int j = 0; j < len; j += 8)
                    {
                        data[j + 0] = 0x55;
                        data[j + 1] = 0x55;
                        data[j + 2] = 0x55;
                        data[j + 3] = 0x55;
                        data[j + 4] = 0xAA;
                        data[j + 5] = 0xAA;
                        data[j + 6] = 0xAA;
                        data[j + 7] = 0xAA;
                    }
                }
                if (i == 4)
                {
                    for (int j = 0; j < len; j += 8)
                    {
                        data[j + 0] = 0;
                        data[j + 1] = 0;
                        data[j + 2] = 0;
                        data[j + 3] = 0;
                        data[j + 4] = 0xFF;
                        data[j + 5] = 0xFF;
                        data[j + 6] = 0xFF;
                        data[j + 7] = 0xFF;
                    }
                }

                for (uint baseAddr = 0; baseAddr < len; baseAddr += 1024 * 1024)//data.Length
                {
                    byte[] temp = new byte[1024 * 1024];
                    for (int j = 0; j < 1024 * 1024; j++)
                    {
                        temp[j] = data[baseAddr + j];
                    }
                    mainForm.writeMem(baseAddr, temp);

                    this.Text = "write:" + i + " " + baseAddr.ToString() + " " + Math.Floor(baseAddr * 100.0 / len);
                    Application.DoEvents();
                }
                byte[] readout = new byte[len];
                for (uint baseAddr = 0; baseAddr < len; baseAddr += 1024 * 1024)//data.Length
                {
                    byte[] temp = new byte[1024 * 1024];
                    mainForm.readMem(baseAddr, temp);
                    for (int j = 0; j < 1024 * 1024; j++)
                    {
                        readout[baseAddr + j] = temp[j];
                    }
                    this.Text = "read:" + i + " " + baseAddr.ToString() + " " + Math.Floor(baseAddr * 100.0 / len);
                    Application.DoEvents();
                }
                for (uint baseAddr = 0; baseAddr < len; baseAddr += 1024)//data.Length
                {
                    bool err = false;
                    int errCount = 0;
                    for (uint k = 0; k < 1024; k += 4)
                    {
                        if (readout[k + 0 + baseAddr] != data[k + 0 + baseAddr])
                        {
                            err = true; errCount++;
                        }
                        if (readout[k + 1 + baseAddr] != data[k + 1 + baseAddr])
                        {
                            err = true; errCount++;
                        }
                        if (readout[k + 2 + baseAddr] != data[k + 2 + baseAddr])
                        {
                            err = true; errCount++;
                        }
                        if (readout[k + 3 + baseAddr] != data[k + 3 + baseAddr])
                        {
                            err = true; errCount++;
                        }
                    }
                    uint x = (baseAddr / 1024) & 0xFF;
                    uint y = (baseAddr / 1024) >> 8;
                    if (errCount > 255) errCount = 255;
                    if (err)
                    {
                        bmp.SetPixel((int)x, (int)y, Color.FromArgb(0xFF, errCount, 0, 0));
                    }
                    else
                    {
                        bmp.SetPixel((int)x, (int)y, Color.FromArgb(0xFF, 0, 0xFF, 0));
                    }
                }

                this.pictureBox1.Image = bmp;
                bmp.Save("temp" + i + ".bmp", ImageFormat.Bmp);
            }
        }

        void testComp(float a, float b)
        {

            mainForm.sendCmd(0x08, Util.convert(a));
            mainForm.sendCmd(0x09, Util.convert(b));
            mainForm.sendCmd(0x0A, 0);
            for (int i = 0; i < 5; i++)
            {
                mainForm.sendCmd(0x0B, (uint)i);
                uint ret = mainForm.sendCmdRet(0x0C);

                Console.Write(a + " " + b + "  ");
                Console.Write(i + ": ");
                Console.Write(((ret & 1) == 0) ? "1 " : "0 ");
                Console.Write(((ret & 2) == 0) ? "1 " : "0 ");
                Console.Write(((ret & 4) == 0) ? "1 " : "0 ");
                Console.Write(((ret & 8) == 0) ? "1 " : "0 ");
                Console.Write(((ret & 16) == 0) ? "1 " : "0 ");
                Console.Write(((ret & 32) == 0) ? "1 " : "0 ");
                Console.WriteLine();
            }
            Console.WriteLine();

        }

        private void button1_Click(object sender, EventArgs e)
        {

            //8'h08 : begin debug_data_send<=1; floatA_temp <= data; command_ack<=1; end//SET_DEBUG_ADDRESS
            //8'h09 : begin debug_data_send<=1; floatB_temp <= data; command_ack<=1; end//SET_DEBUG_ADDRESS
            //8'h0A : begin debug_data_send<=1; floatA <= floatA_temp; floatB <= floatB_temp; float_count <= 0; add_sub<=data[0]; command_ack<=1; end//SET_DEBUG_ADDRESS
            //8'h0B : begin debug_data_send<=1; float_debug_addr <= data[7:0]; command_ack<=1; end//SET_DEBUG_ADDRESS
            //8'h0C : begin debug_data_send<=1; command_ack<=1; end

            testComp(1f, 1f);
            testComp(2f, 1f);
            testComp(1f, 2f);


            mainForm.sendCmd(0x08, Util.convert(1.0f));
            mainForm.sendCmd(0x09, Util.convert(11.0f));
            mainForm.sendCmd(0x0A, 0);
            for (int i = 0; i < 25; i++)
            {
                mainForm.sendCmd(0x0B, (uint)i);
                uint ret = mainForm.sendCmdRet(0x0C);

                float v = Util.convert(ret);
                Console.WriteLine(i + ":" + v);
            }




        }

        string[] dict = new string[] {
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"J",
"K",
"L",
"M",
"N",
"P",
"R",
"T",
"U",
"V",
"W",
"Y",
"AA",
"AB",
"AC",
"AD",
"AE",
"AF",
"AG",
"AH",
};

        private void button2_Click(object sender, EventArgs e)
        {
            uint[] values = new uint[32];
            for (uint addr = 0; addr < 28; addr++)
            {
                mainForm.sendCmd(0x16, addr);
                uint ret = mainForm.sendCmdRet(0x2f);//pinvalue
                values[addr] = ret;
            }
            int idx = 0;

            uint[] diff = new uint[32];
            for (uint addr = 0; addr < 28; addr++)
            {
                mainForm.sendCmd(0x16, addr);
                uint ret = mainForm.sendCmdRet(0x2f);//pinvalue
                diff[addr] = ret ^ values[addr];
                values[addr] = ret;
            }
            for (uint j = 0; j < 28; j++)
            {
                string line = "";
                for (uint i = 0; i < 28; i++)
                {
                    uint f = (values[j] >> ((int)i)) & 1;

                    line = f + "," + line;

                }
                Console.WriteLine(line);
            }


            while (true)
            {
                idx++;
                for (uint addr = 0; addr < 28; addr++)
                {
                    mainForm.sendCmd(0x16, addr);
                    uint ret = mainForm.sendCmdRet(0x2f);//pinvalue
                    diff[addr] = ret ^ values[addr];
                    values[addr] = ret;
                }

                for (uint j = 0; j < 28; j++)
                {
                    for (uint i = 0; i < 28; i++)
                    {
                        uint f = (diff[j] >> ((int)i)) & 1;

                        if (f != 0)
                        {
                            var name = dict[j] + (i + 1);
                            Console.Write(name + ",");
                        }
                    }
                }

                Thread.Sleep(10);
            }
        }

        uint addr = 0;
        byte[][] buffs;

        private void button4_Click(object sender, EventArgs e)
        {
            uint last1 = 0;
            uint last2 = 0;
            while (true)
            {
                uint ret1 = mainForm.sendCmdRet(0x2E);//pinvalue
                uint ret2 = mainForm.sendCmdRet(0x2F);//pinvalue

                Console.Write(".");
                if ((ret1 ^ last1) != 0 || (ret2 ^ last2) != 0)
                {
                    Console.Write("\r\n" + Util.getHex8(ret1 ^ last1) + " " + Util.getHex8(ret2 ^ last2));
                }
                last1 = ret1;
                last2 = ret2;
                Thread.Sleep(100);
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            Random r = new Random();
            Stopwatch sw = new Stopwatch();
            sw.Start();
            int err = 0;
            for (int i = 0; i < 1000; i++)
            {
                uint val = (uint)r.Next(int.MinValue, int.MaxValue);
                uint echo = mainForm.sendCmdRet(Form1.GET_CONST_ECHO, val);
                if (echo != val)
                {
                    err++;
                }
            }
            sw.Stop();

            Console.WriteLine(sw.ElapsedMilliseconds + ", err=" + err);
        }

        private void button6_Click(object sender, EventArgs e)
        {

            for (uint i = 0; i < 64; i++)
            {
                mainForm.sendCmdRet(Form1.SET_DEBUG_ADDRESS, i);
                Console.WriteLine(i);

                Thread.Sleep(4000);
            }
        }

        //int size = 32 * 1024;
        private void button8_Click(object sender, EventArgs e)//send
        {
            Random r = new Random();
            int batchCount = 1;
            try
            {
                buffs = new byte[batchCount][];
                // write mem
                int size = testSize;
                for (int i = 0; i < batchCount; i++)
                {
                    buffs[i] = new byte[size];
                    r.NextBytes(buffs[i]);

                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    writeMem00XX(buffs[i], size, i * testSize);
                    sw.Stop();

                    double speed = (testSize / 1024.0 / 1024.0) / (sw.ElapsedMilliseconds / 1000.0);
                    Console.WriteLine("i:" + i + ",done, " + speed + "M/s");
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

        }

        private void button12_Click(object sender, EventArgs e)
        {
            int batchCount = 1;
            int size = testSize;
            byte[] buffr = new byte[size];
            for (int i = 0; i < batchCount; i++)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                readMem00XX(buffr, size, i * testSize);
                sw.Stop();
                double speed = (testSize / 1024.0 / 1024.0) / (sw.ElapsedMilliseconds / 1000.0);

                Console.WriteLine("speed:" + speed + "M/s");

                Form1.compair(size, buffs[i], buffr, 0, 32);
            }
        }

        private void button13_Click(object sender, EventArgs e)
        {/*
            try
            {
                uint cnt = 30;// mainForm.sendCmdRet(0x25, 0);
                Console.WriteLine("cnt:" + cnt);

                FileStream fs = new FileStream("e:\\record.csv", FileMode.Create, FileAccess.Write);
                StreamWriter sw = new StreamWriter(fs);

                string head = "";
                head += "idx addr=" + addr + " ,";

                head += "v1,";

                head += "h,";
                head += "l,";

                for (int f = 0; f < 32; f++)
                {
                    head += (31 - f) + ",";
                }

                for (int f = 0; f < 32; f++)
                {
                    head += (31 - f) + ",";
                }
                head += "h,";
                head += "l,";


                for (int f = 0; f < 32; f++)
                {
                    head += (31 - f) + ",";
                }

                for (int f = 0; f < 32; f++)
                {
                    head += (31 - f) + ",";
                }
                sw.WriteLine(head);

                for (uint i = 0; i < cnt; i++)
                {
                    mainForm.sendCmdRet(Form1.SET_DEBUG_ADDRESS, i);

                    string line = "";
                    line += i + ",";

                    {
                        uint l = mainForm.sendCmdRet(0x2E, 0);
                        uint h = mainForm.sendCmdRet(0x2F, 0);

                        uint v1 = 0;
                        if (buff != null && i * 4 + 3 < buff.Length)
                        {
                            v1 |= (((uint)buff[i * 4 + 0]) & 0xFF);
                            v1 |= (((uint)buff[i * 4 + 1]) & 0xFF) << 8;
                            v1 |= (((uint)buff[i * 4 + 2]) & 0xFF) << 16;
                            v1 |= (((uint)buff[i * 4 + 3]) & 0xFF) << 24;
                        }

                        line += Util.getHex8(v1) + ",";

                        //line += hh + ",";
                        //line += gg + ",";
                        //line += ff + ",";
                        line += Util.getHex8(h) + ",";
                        line += l + ",";

                        for (int f = 0; f < 32; f++)
                        {
                            uint v = h & 0x80000000;
                            line += ((v != 0) ? "1" : " ") + ",";
                            h = h << 1;
                        }

                    }
                    
                    sw.WriteLine(line);
                }

                sw.Close();
                fs.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.WriteLine("done");*/
        }

        struct TestData
        {
            public int addr;
            public byte[] data;
        }
        
        private void button14_Click(object sender, EventArgs e)
        {
            uint value;
            byte[] rbuff = new byte[1024];
            {
                mainForm.setmem(0x5C000800, 0);//ddr_addr
                mainForm.setmem(0x5C000C00, 0);//read req
                mainForm.readMem(0x5C000000, rbuff);//rdbuf
                for (int i = 0; i < 16; i++)
                {
                    for (int j = 0; j < 16; j++)
                    {
                        Console.Write(Util.getHex2(rbuff[i * 16 + j]));
                    }
                    Console.WriteLine();
                }

                value = mainForm.getmem(0x5C001400);
                Console.WriteLine((value >> 16) + " " + (value & 65535));

            }
            TestData[] testdata = new TestData[64];
            int index = 0;
            Random r = new Random();
            while (index < testdata.Length)
            {
                int addr = (int)(r.NextDouble() * 256.0 * 1024.0 * 1024.0);
                addr /= 256;
                addr *= 256;

                bool found = false;
                for (int i = 0; i < index; i++)
                {
                    if (addr == testdata[i].addr)
                    {
                        found = true;
                        Console.WriteLine("found");
                    }
                }
                if (found)
                {
                    continue;
                }
                testdata[index].addr = addr;
                testdata[index].data = new byte[1024];

                r.NextBytes(testdata[index].data);

                index++;
            }

            for (index = 0; index < testdata.Length; index++)
            {
                mainForm.setmem(0x5C000800, (uint)testdata[index].addr);//ddr_addr
                mainForm.writeMem(0x5C000400, testdata[index].data);//wrbuf
                mainForm.setmem(0x5C001000, 0);//write req
            }

            bool error = false;
            for (index = 0; index < testdata.Length; index++)
            {
                mainForm.setmem(0x5C000800, (uint)testdata[index].addr);//ddr_addr
                mainForm.setmem(0x5C000C00, 0);//read req
                mainForm.readMem(0x5C000000, rbuff);//rdbuf
                for (int i = 0; i < 256; i++)
                {
                    if (testdata[index].data[i] != rbuff[i])
                    {
                        error = true;
                    }
                }

            }

            Console.WriteLine(error);

            //mainForm.readMem(0x5C001C00, misc);

            value = mainForm.getmem(0x5C001400);

            Console.WriteLine(value);

            Console.WriteLine(Util.getBin8(value >> 8) + " " + Util.getBin8(value));



            //   uint n1 = 2;
            //   uint n2 = 1;
            //   for (var i = 0; i < 30; i++)
            //   {
            //       mainForm.sendCmd(Form1.SET_DEBUG_WRITEDATA, 0);//n1+n2
            //       uint val2 = mainForm.sendCmdRet(0x2F);
            //       Console.WriteLine(Util.getHex8(val2));
            //       uint q_leading1 = (val2 >> 0) & 31;
            //       uint q_leading = (val2 >> 5) & 31;
            //       uint q_trailing1 = (val2 >> 10) & 31;
            //       uint q_trailing = (val2 >> 15) & 31;
            //       Console.WriteLine("q_trailing:" + q_trailing + " q_trailing1:" + q_trailing1 + " q_leading:" + q_leading + " q_leading1:" + q_leading1);
            //   
            //       n1 *= 2;
            //       n2 *= 2;
            //       //8'h2F: begin debug_data_out<={q_trailing, q_trailing1, q_leading, q_leading1}; end
            //   }

            //Random r = new Random();
            //for (int j = 0; j < 1000; j++)
            //{
            //    for (int i = -32; i < 32; i++)
            //    {
            //        uint v = (uint)r.Next();
            //        uint s = (uint)i;
            //        mainForm.sendCmd(Form1.SET_DEBUG_WRITEDATA, v);
            //        mainForm.sendCmd(Form1.SET_DEBUG_ADDRESS, s);// >> 1
            //
            //        uint val1 = mainForm.sendCmdRet(0x2E);
            //        uint val2 = mainForm.sendCmdRet(0x2F);
            //        if (val1 != val2)
            //        {
            //            Console.WriteLine(Util.getHex8(val1));
            //            Console.WriteLine(Util.getHex8(val2));
            //        }
            //    }
            //}
        }

        private void button15_Click(object sender, EventArgs e)
        {/*
            int size = 16 * 1024 * 1024;
            Random rnd = new Random();
            for (int r = 0; r < 64; r++)
            {
                // write mem
                buff = new byte[size];
                rnd.NextBytes(buff);

                writeMem(buff, size, 0);
                byte[] buff2 = new byte[size];
                readMem(buff2, size, 0);
                int err = 0;
                for (int i = 0; i < size; i++)
                {
                    if (buff2[i] != buff[i])
                    {
                        err++;
                    }
                }
                Console.WriteLine("r=" + r + ", err=" + err);
            }*/
        }

        private void button16_Click(object sender, EventArgs e)
        {
            int size = 16 * 1024 * 1024;
            Random rnd = new Random();
            byte[] buffAll = new byte[512 * 1024 * 1024];
            rnd.NextBytes(buffAll);

            byte[] buff = new byte[size];

            Console.WriteLine("start");
            for (int r = 0; r < 32; r++)//32
            {
                int addr = r * size;
                for (int i = 0; i < size; i++)
                {
                    buff[i] = buffAll[i+addr];
                }
                // write mem

                writeMem(buff, size, addr);
                Console.WriteLine("r=" + r );
                
            }

            for (int r = 0; r < 32; r++)
            {
                int addr = r * size;
               
                byte[] buff2 = new byte[size];

                readMem(buff2, size, addr);
                int err = 0;
                for (int i = 0; i < size; i++)
                {
                    if (buff2[i] != buffAll[i + addr])
                    {
                        err++;
                    }
                }
                Console.WriteLine("r=" + r + ", err=" + err);
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {

            mainForm.sendCmdRet(0x14, this.checkBox1.Checked ? 1u : 0u); //force record
        }

        private void button17_Click(object sender, EventArgs e)
        {
           
        }

        private void button19_Click(object sender, EventArgs e)
        {
            bool bResult = mainForm.pc2fpgaReq();
            Console.WriteLine("done");

            uint flg = mainForm.sendCmdRet(0x2A);

            Console.WriteLine("flg:" + Util.getBin8(flg));
        }

        private void button18_Click(object sender, EventArgs e)
        {
          
        }

        private void button20_Click(object sender, EventArgs e)
        {
            bool bResult = mainForm.fpga2pcReq();
            Console.WriteLine("done");

            uint flg = mainForm.sendCmdRet(0x2A);

            Console.WriteLine("flg:" + Util.getBin8(flg));
        }

        int testSize = 16 * 1024 * 1024;
        private void button21_Click(object sender, EventArgs e)
        {
            buffs = new byte[1][];
            try
            {
                // write mem
                int size = testSize;
                buffs[0] = new byte[size];
                Random r = new Random();
                r.NextBytes(buffs[0]);
                Stopwatch sw = new Stopwatch();
                sw.Start();
                writeMemHalf(buffs[0], size, 0);
                sw.Stop();

                double speed = (testSize / 1024.0 / 1024.0) / (sw.ElapsedMilliseconds / 1000.0);
                Console.WriteLine("done, " + speed + "M/s");
            }
            catch (Exception ex) {
                Console.WriteLine(ex);
            }
        }

        private void button22_Click(object sender, EventArgs e)
        {
            try
            {
                int size = testSize;
                byte[] buff2 = new byte[size];
                Stopwatch sw = new Stopwatch();
                sw.Start();
                readMemHalf(buff2, size, 0);

                Form1.compair(size, buffs[0], buff2, 60, 32);

                double speed = (testSize / 1024.0 / 1024.0) / (sw.ElapsedMilliseconds / 1000.0);

                Console.WriteLine("speed: " + speed + "M/s");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

        }

        private void button3_Click(object sender, EventArgs e)
        {
            buffs = new byte[1][];
            try
            {
                // write mem
                int size = testSize;
                buffs[0] = new byte[size];
                Random r = new Random();
                r.NextBytes(buffs[0]);
                Stopwatch sw = new Stopwatch();
                sw.Start();
                writeMem(buffs[0], size, 0);
                sw.Stop();

                double speed = (testSize / 1024.0 / 1024.0) / (sw.ElapsedMilliseconds / 1000.0);
                Console.WriteLine("done, " + speed + "M/s");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            //Console.WriteLine(Util.getHex8( buffs[0][0x00fffc00 + 17*4]));
        }

        private void button9_Click(object sender, EventArgs e)
        {
            try
            {
                int size = testSize;
                byte[] buff2 = new byte[size];
                Stopwatch sw = new Stopwatch();
                sw.Start();
                readMem(buff2, size, 0);

                Form1.compair(size, buffs[0], buff2, 60, 32);

                double speed = (testSize / 1024.0 / 1024.0) / (sw.ElapsedMilliseconds / 1000.0);

                Console.WriteLine("speed: " + speed + "M/s");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

        }

        //const int TRANS_COUNT = 4;
        const int TRANS_COUNT_HALF = 32;//512byte
        //const int TRANS_COUNT = 64;//1024byte
        void writeMemHalf(byte[] buff,int size, int addr) { // byte size byte address
            mainForm.sendCmd(0x10, (uint)(size / (4 * (4 * TRANS_COUNT_HALF)) - 1));//ddr2_trans_end
            mainForm.sendCmd(Form1.SET_DEBUG_ADDRESS, (uint)(addr / 4));//debug_address

            int xferLen = size;

            mainForm.sendCmd(0x02, 1);//reset_fifo
            mainForm.sendCmd(0x02, 0);//reset_fifo

            mainForm.sendCmd(0x05, 0);//single_transfer
            mainForm.sendCmd(0x01, 0);//ft_out_to_pc

            mainForm.sendCmd(0x04, 1);//transfer_req
            bool bResult = mainForm.pc2fpgaTrans(ref buff, ref xferLen);
            //Thread.Sleep(10);
            while (true) {
                uint mem_status = mainForm.sendCmdRet(0x2A);
                if (mem_status == 15) {
                    break;
                }
            }

            mainForm.sendCmd(0x04, 0);//transfer_req
        }

        void readMemHalf(byte[] buff, int size, int addr) { // byte size byte address
            //read mem
            mainForm.sendCmd(0x10, (uint)(size / (4 * (4 * TRANS_COUNT_HALF)) - 1));//ddr2_trans_end
            mainForm.sendCmd(Form1.SET_DEBUG_ADDRESS, (uint)(addr / 4));//debug_address

            int xferLen = size;

            mainForm.sendCmd(0x02, 1);//reset_fifo
            mainForm.sendCmd(0x02, 0);//reset_fifo

            mainForm.sendCmd(0x05, 0);//single_transfer
            mainForm.sendCmd(0x01, 1);//ft_out_to_pc

            mainForm.sendCmd(0x04, 1);//transfer_req
            bool bResult = mainForm.fpga2pcTrans(ref buff, ref xferLen);
            //Thread.Sleep(100);
            while (true)
            {
                uint mem_status = mainForm.sendCmdRet(0x2A);
                if (mem_status == 15)
                {
                    break;
                }
            }

            Thread.Sleep(10);
            mainForm.sendCmd(0x04, 0);//transfer_req
        }



        //const int TRANS_COUNT = 4;
        const int TRANS_COUNT = 64;//512byte
        //const int TRANS_COUNT = 64;//1024byte
        void writeMem(byte[] buff, int size, int addr)
        { // byte size byte address
            mainForm.sendCmd(0x10, (uint)(size / (4 * (4 * TRANS_COUNT)) - 1));//ddr2_trans_end
            mainForm.sendCmd(Form1.SET_DEBUG_ADDRESS, (uint)(addr / 4));//debug_address

            int xferLen = size;

            mainForm.sendCmd(0x02, 1);//reset_fifo
            mainForm.sendCmd(0x02, 0);//reset_fifo

            mainForm.sendCmd(0x05, 0);//single_transfer
            mainForm.sendCmd(0x01, 0);//ft_out_to_pc

            mainForm.sendCmd(0x04, 1);//transfer_req
            bool bResult = mainForm.pc2fpgaTrans(ref buff, ref xferLen);
            //Thread.Sleep(10);
            while (true)
            {
                uint mem_status = mainForm.sendCmdRet(0x2A);
                if (mem_status == 15)
                {
                    break;
                }
            }

            mainForm.sendCmd(0x04, 0);//transfer_req
        }

        void readMem(byte[] buff, int size, int addr)
        { // byte size byte address
            //read mem
            mainForm.sendCmd(0x10, (uint)(size / (4 * (4 * TRANS_COUNT)) - 1));//ddr2_trans_end
            mainForm.sendCmd(Form1.SET_DEBUG_ADDRESS, (uint)(addr / 4));//debug_address

            int xferLen = size;

            mainForm.sendCmd(0x02, 1);//reset_fifo
            mainForm.sendCmd(0x02, 0);//reset_fifo

            mainForm.sendCmd(0x05, 0);//single_transfer
            mainForm.sendCmd(0x01, 1);//ft_out_to_pc

            mainForm.sendCmd(0x04, 1);//transfer_req
            bool bResult = mainForm.fpga2pcTrans(ref buff, ref xferLen);
            //Thread.Sleep(100);
            while (true)
            {
                uint mem_status = mainForm.sendCmdRet(0x2A);
                if (mem_status == 15)
                {
                    break;
                }
            }

            Thread.Sleep(10);
            mainForm.sendCmd(0x04, 0);//transfer_req
        }


        //const int TRANS_COUNT00XX = 4;
        //const int TRANS_COUNT00XX = 32;//512byte
        const int TRANS_COUNT00XX = 64;//1024byte
        void writeMem00XX(byte[] buff, int size, int addr)
        { // byte size byte address
            mainForm.sendCmd(0x10, (uint)(size * 2 / (4 * (4 * TRANS_COUNT00XX)) - 1));//ddr2_trans_end
            mainForm.sendCmd(Form1.SET_DEBUG_ADDRESS, (uint)(addr * 2 / 4));//debug_address

            int xferLen = size * 2;
            byte[] buff2 = new byte[buff.Length * 2];
            for (int i = 0; i < size; i+=4)
            {
                buff2[i * 2 + 0] = buff[i + 0];
                buff2[i * 2 + 1] = buff[i + 1];
                buff2[i * 2 + 2] = buff[i + 2];
                buff2[i * 2 + 3] = buff[i + 3];
            }

            mainForm.sendCmd(0x02, 1);//reset_fifo
            mainForm.sendCmd(0x02, 0);//reset_fifo

            mainForm.sendCmd(0x05, 0);//single_transfer
            mainForm.sendCmd(0x01, 0);//ft_out_to_pc

            mainForm.sendCmd(0x04, 1);//transfer_req
            bool bResult = mainForm.pc2fpgaTrans(ref buff2, ref xferLen);
            //Thread.Sleep(10);
            while (true)
            {
                uint mem_status = mainForm.sendCmdRet(0x2A);
                if (mem_status == 15)
                {
                    break;
                }
            }

            mainForm.sendCmd(0x04, 0);//transfer_req
        }

        void readMem00XX(byte[] buff, int size, int addr)
        { // byte size byte address
            //read mem
            mainForm.sendCmd(0x10, (uint)(size * 2 / (4 * (4 * TRANS_COUNT00XX)) - 1));//ddr2_trans_end
            mainForm.sendCmd(Form1.SET_DEBUG_ADDRESS, (uint)(addr*2 / 4));//debug_address

            int xferLen = size*2;

            mainForm.sendCmd(0x02, 1);//reset_fifo
            mainForm.sendCmd(0x02, 0);//reset_fifo

            mainForm.sendCmd(0x05, 0);//single_transfer
            mainForm.sendCmd(0x01, 1);//ft_out_to_pc
            byte[] buff2 = new byte[buff.Length * 2];

            mainForm.sendCmd(0x04, 1);//transfer_req
            bool bResult = mainForm.fpga2pcTrans(ref buff2, ref xferLen);
            //Thread.Sleep(100);
            while (true)
            {
                uint mem_status = mainForm.sendCmdRet(0x2A);
                if (mem_status == 15)
                {
                    break;
                }
            }

            Thread.Sleep(10);
            mainForm.sendCmd(0x04, 0);//transfer_req

            for (int i = 0; i < size; i+=4)
            {
                buff[i + 0] = buff2[i * 2 + 0];
                buff[i + 1] = buff2[i * 2 + 1];
                buff[i + 2] = buff2[i * 2 + 2];
                buff[i + 3] = buff2[i * 2 + 3];
            }

        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox2.Checked)
            {
                testSize = 16 * 1024 * 1024;
            }
            else
            {
                testSize = 16 * 1024;
            }
        }

    }
}
